package com.gin.kotlin.no_gay_alliance.runner

import android.util.Log
import com.gin.kotlin.no_gay_alliance.app.App
import com.gin.kotlin.no_gay_alliance.app.AppRunner
import com.gin.kotlin.no_gay_alliance.callback.RCallback
import com.gin.kotlin.no_gay_alliance.callback.SCallback
import com.gin.kotlin.no_gay_alliance.interceptor.LoggingInterceptor
import com.gin.kotlin.no_gay_alliance.interceptor.ResourceInterceptor
import com.gin.kotlin.no_gay_alliance.model.AvatarBuffModel
import com.gin.kotlin.no_gay_alliance.model.ItemTypeModel
import com.gin.kotlin.no_gay_alliance.model.emoji.EmojiPackageModel
import com.gin.kotlin.no_gay_alliance.model.emoji.GenericEmojiGroup
import com.gin.kotlin.no_gay_alliance.model.emoji.GenericEmojiPackage
import com.gin.kotlin.no_gay_alliance.provider.ngajs.AvatarBuffProvider
import com.gin.kotlin.no_gay_alliance.provider.ngajs.EmoteGroupsProvider
import com.gin.kotlin.no_gay_alliance.provider.ngajs.IndexForumsProvider
import com.gin.kotlin.no_gay_alliance.provider.ngaphp.ItemTypeProvider
import com.gin.kotlin.no_gay_alliance.provider.thirdparty.EmojiPackageProvider
import com.gin.kotlin.no_gay_alliance.provider.thirdparty.EmojiUrlProvider
import com.gin.kotlin.no_gay_alliance.store.GlobalProperty
import com.gin.kotlin.no_gay_alliance.worker.ImagePreloadWorker
import com.gin.nga.enums.param.ItemType
import com.gin.nga.main.NgaResource
import com.gin.nga.response.resource.bbscode.EmoteGroup
import com.gin.nga.response.resource.ui.AvatarBuff
import okhttp3.Cache
import java.io.File
import java.io.IOException
import java.util.concurrent.CountDownLatch

/**
 * 更新静态资源
 */
class ResourceRunner : AppRunner {
    /**
     * 执行的任务内容
     * @param app [App]
     */
    override fun run(app: App) {
        // 静态资源API
        val api = NgaResource.Builder().also {
            it.clientBuilder
                .addInterceptor(LoggingInterceptor())
                .addInterceptor(ResourceInterceptor())
                // 配置缓存目录
                .cache(Cache(File(app.cacheDir, "static"), 50 * App.MB))
        }.build().api
        app.resourceApi = api

        //更新官方表情
        EmoteGroupsProvider.getInstance().enqueue(callback = object : SCallback<List<EmoteGroup>> {
            override fun onSuccess(data: List<EmoteGroup>) {
                App.INSTANCE.emoteGroup = data
            }

            override fun onFailure(call: okhttp3.Call, e: IOException) {
                Log.w(TAG, "官方表情加载失败")
                e.printStackTrace()
            }
        })

        //更新头像buff
        AvatarBuffProvider.getInstance().enqueue(callback = object : SCallback<List<AvatarBuff>> {
            override fun onSuccess(data: List<AvatarBuff>) {
                val buffs = data.map { AvatarBuffModel(it) }
                App.INSTANCE.avatarBuffs = buffs

                // 填充道具信息
                ItemTypeProvider.getInstance().enqueue(ItemType.TO_USER, data.mapNotNull { it.id }, callback = object : RCallback<List<ItemTypeModel>, List<Pair<Int, Int>>> {
                    override fun onSuccess(data: List<ItemTypeModel>, ignoreCache: Boolean) {
                        buffs.forEach { buff -> data.firstOrNull { buff.id == it.subTypeId }.also { buff.itemTypeModel = it } }
                    }

                    override fun onError(errorMessage: String) {
                        Log.w(TAG, "onError: $errorMessage")
                    }
                })

            }

            override fun onFailure(call: okhttp3.Call, e: IOException) {
                Log.w(TAG, "头像buff加载失败")
                e.printStackTrace()
            }
        })

        // 更新论坛首页入口
        IndexForumsProvider.getInstance().enqueue()

        // 获取第三方表情包
        EmojiUrlProvider.getInstance().enqueue(callback = object : SCallback<List<String>> {
            override fun onSuccess(data: List<String>) {
                Thread {
                    // 计数器
                    val latch = CountDownLatch(data.size)
                    val packages = mutableListOf<EmojiPackageModel>()
                    data.forEach {
                        EmojiPackageProvider.getInstance().enqueue(it, callback = object : SCallback<EmojiPackageModel> {
                            override fun onSuccess(data: EmojiPackageModel) {
                                packages.add(data)
                                latch.countDown()
                            }

                            override fun onFailure(call: okhttp3.Call, e: IOException) {
                                e.printStackTrace()
                                latch.countDown()
                            }
                        })
                    }
                    // 等待请求结束
                    latch.await()

                    Log.i(TAG, "获取到第三方表情包: ${packages.size} 个")
                    // 排序
                    packages.sortedByDescending { it.name }

                    App.INSTANCE.emojiPackages = packages

                    // 已缓存的路径
                    val preloadedUrls = ImagePreloadWorker.getCacheFile(app).readText().split("\\n")
                    // 提交自动缓存任务
                    val hidden = GlobalProperty.getInstance().hiddenGenericEmojiGroup
                    val list = packages.asSequence().map { GenericEmojiPackage(it) }
                        .flatMap { it.groups ?: listOf() }
                        // 优先加载选中的表情包
                        .sortedWith(object : Comparator<GenericEmojiGroup> {
                            override fun compare(o1: GenericEmojiGroup?, o2: GenericEmojiGroup?): Int {
                                val h1 = hidden.contains(o1?.getUniqueName())
                                val h2 = hidden.contains(o2?.getUniqueName())
                                if (h1 && !h2) return 1
                                if (!h1 && h2) return -1
                                return 0
                            }
                        })
                        // 过滤掉未选中表情包
//                        .filter{!hidden.contains(it.getUniqueName())}
                        .flatMap { it.data ?: listOf() }
                        .mapNotNull { it.url }
                        // 过滤掉已缓存路径
                        .filter { !preloadedUrls.contains(it) }
                        .toList()
                    ImagePreloadWorker.start(list)
                }.start()
            }

            override fun onFailure(call: okhttp3.Call, e: IOException) {
                e.printStackTrace()
            }
        })


    }

    companion object {
        private val TAG = ResourceRunner::class.java.simpleName
    }
}